#include "lcd_fsmc.h"
#include "lcd_data.h"


// 定义当前背景颜色
Color_Size Background = White;


/*
	显示屏关键数据
*/
_lcd_dev lcddev = 
{
	.LCD_Height = 480, // 高度(默认竖屏)
	.LCD_Width = 320,  // 宽度(默认竖屏)
	.DIR = 0, // 竖屏
	.wxram = 0x2A, // 设置x坐标命令
	.wyram = 0x2B, // 设置y坐标命令
	.setram  = 0x2C,// 写入内存命令
};


#if USE_FSMC_DMA
// FSMC使用DMA,使用内存到内存模式可以指定任意通道
void LCD_FSMC_DMA_Config(void)
{
	DMA_InitTypeDef DMA_Initstruct;
	NVIC_InitTypeDef NVIC_Initstruct;

	// 初始化时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);

	DMA_DeInit(LCD_DMA_Stream);

	while (DMA_GetCmdStatus(LCD_DMA_Stream) != DISABLE){}//等待DMA可配置 

	DMA_Initstruct.DMA_Mode = DMA_Mode_Normal;
	DMA_Initstruct.DMA_Channel = LCD_DMA_Channel;
	DMA_Initstruct.DMA_DIR = DMA_DIR_MemoryToMemory; // 存储器到存储器模式
	DMA_Initstruct.DMA_BufferSize = 0; // 后续指定
	DMA_Initstruct.DMA_Memory0BaseAddr = (uint32_t)&LCD->LCD_DATA;
	DMA_Initstruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; // 单次突发传输
	DMA_Initstruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 半字传输
	DMA_Initstruct.DMA_MemoryInc = DMA_MemoryInc_Disable; // 内存地址不自增
	DMA_Initstruct.DMA_PeripheralBaseAddr = (uint32_t)0; // 外设地址，后续指定
	DMA_Initstruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // 单次突发传输
	DMA_Initstruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 半字传输
	DMA_Initstruct.DMA_PeripheralInc = DMA_PeripheralInc_Enable; // 外设自增
	DMA_Initstruct.DMA_Priority = DMA_Priority_High; // 优先级高
	DMA_Initstruct.DMA_FIFOMode = DMA_FIFOMode_Disable; // 不使用FIFO
	DMA_Initstruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; // 不使用,随便
	DMA_Init(LCD_DMA_Stream,&DMA_Initstruct);

	// 使能DMA传输完成中断
	DMA_ITConfig(LCD_DMA_Stream,DMA_IT_TC,ENABLE);

	NVIC_Initstruct.NVIC_IRQChannel = LCD_DMA_IRQn;
	NVIC_Initstruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Initstruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_Initstruct.NVIC_IRQChannelSubPriority = 2;
	NVIC_Init(&NVIC_Initstruct);

}

// LCD启动一次传输
void LCD_FSMC_Transfer(uint16_t xs,uint16_t ys,uint16_t xe,uint16_t ye,uint16_t *color)
{
	LCD_SetArea(xs,xe,ys,ye);
	uint32_t count = ((xe-xs+1)*(ye-ys+1)) / 0xFFFF;
	uint32_t remain = ((xe-xs+1)*(ye-ys+1)) % 0xFFFF;
	DMA_Cmd(LCD_DMA_Stream, DISABLE);  //关闭DMA传输 
	while (DMA_GetCmdStatus(LCD_DMA_Stream) != DISABLE){}     //等待DMA可配置 
	LCD_DMA_Stream->PAR  = (uint32_t)color; //传输数组
	// 如果大于65535分两次发
	if(count)
	{    
		DMA_Cmd(LCD_DMA_Stream, DISABLE);  //关闭DMA传输 
		while (DMA_GetCmdStatus(LCD_DMA_Stream) != DISABLE){}     //等待DMA可配置 
		LCD_DMA_Stream->NDTR = 0xFFFF; //数据传输量  
		DMA_Cmd(LCD_DMA_Stream, ENABLE);    //开启DMA传输  
		// 等待传输完成
		while(DMA_GetITStatus(LCD_DMA_Stream,LCD_DMA_IT_TCIFx) == RESET);
	}

	DMA_Cmd(LCD_DMA_Stream, DISABLE);  //关闭DMA传输 
	while (DMA_GetCmdStatus(LCD_DMA_Stream) != DISABLE);  //等待DMA可配置 
	LCD_DMA_Stream->NDTR = (uint16_t)remain;  //数据传输量  
	DMA_Cmd(LCD_DMA_Stream, ENABLE);    //开启DMA传输 
}

#endif // USE_FSMC_DMA


// LCD初始化使用的延迟
static void LCD_Delay(uint32_t count)
{
	uint32_t i;
	for(i=0;i<count;i++)
	{
		uint32_t uc =1000;
		while(uc--);
	}
}




// 写寄存器(命令)
void LCD_WriteReg(uint16_t reg)
{
	LCD->LCD_REG = reg;
}


// 发送数据
void LCD_WriteData(uint16_t data)
{
	LCD->LCD_DATA = data;
}


// 使用的引脚初始化
void SRAM_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_Initstruct;
    // 时钟初始化
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | 
                            RCC_AHB1Periph_GPIOE,ENABLE);
    // SRAM使用引脚通用配置
    GPIO_Initstruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Initstruct.GPIO_OType = GPIO_OType_PP;
    GPIO_Initstruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Initstruct.GPIO_Speed = GPIO_Speed_100MHz;

    // 地址线配置 A16 --- PD11 --- RS
    GPIO_Initstruct.GPIO_Pin = GPIO_Pin_11;
    GPIO_Init(GPIOD,&GPIO_Initstruct);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource11,GPIO_AF_FSMC);

    // 数据线配置1 \PD0\PD1\PD8\PD9\PD10\PD14\PD15
    GPIO_Initstruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 |
                                GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 |
                                GPIO_Pin_15;
    GPIO_Init(GPIOD,&GPIO_Initstruct);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource10,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_FSMC);

    // 数据线配置2 PE7\PE8\PE9\PE10\PE11\PE12\PE13\PE14\PE15
    GPIO_Initstruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 |
                                GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 |
                                GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_Init(GPIOE,&GPIO_Initstruct);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource7,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource15,GPIO_AF_FSMC);

    // 控制引脚配置 PD4--RD PD5--WR PD7--CS
    GPIO_Initstruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;
    GPIO_Init(GPIOD,&GPIO_Initstruct);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource4,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource7,GPIO_AF_FSMC);
}

// FSMC初始化配置
void FSMC_SRAM_Config(void)
{
    FSMC_NORSRAMInitTypeDef FSMC_Initstruct;
 	FSMC_NORSRAMTimingInitTypeDef  readTiming;
	FSMC_NORSRAMTimingInitTypeDef  writeTiming;
    RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);


    /******时序配置*******/
	// 设置读时序
    //地址建立时间（ADDSET）为1个HCLK
    readTiming.FSMC_AddressSetupTime = 15;
    //地址保持时间（ADDHLD）模式A未用到
    readTiming.FSMC_AddressHoldTime = 3;
    //数据保持时间（DATAST）+ 1个HCLK = 9/168M=54ns(对EM的SRAM芯片)
    readTiming.FSMC_DataSetupTime = 5;
	// 设置写时序
	readTiming.FSMC_AddressSetupTime = 15;
    //地址保持时间（ADDHLD）模式A未用到
    readTiming.FSMC_AddressHoldTime = 0;
    //数据保持时间（DATAST）+ 1个HCLK = 9/168M=54ns(对EM的SRAM芯片)
    readTiming.FSMC_DataSetupTime = 20;

    //设置总线转换周期，仅用于复用模式的NOR操作
    writeTiming.FSMC_BusTurnAroundDuration = readTiming.FSMC_BusTurnAroundDuration = 1;
    //设置时钟分频，仅用于同步类型的存储器
    writeTiming.FSMC_CLKDivision = readTiming.FSMC_CLKDivision = 0x00;
    //数据保持时间，仅用于同步型的NOR
    writeTiming.FSMC_DataLatency = readTiming.FSMC_DataLatency = 0x00;
    //选择匹配SRAM的模式
    writeTiming.FSMC_AccessMode = readTiming.FSMC_AccessMode = FSMC_AccessMode_A;

    /******控制逻辑*******/
    FSMC_Initstruct.FSMC_Bank = FSMC_Bank1_NORSRAM1; // 选择区域
    FSMC_Initstruct.FSMC_DataAddressMux = FSMC_DataAddressMux_Enable; // 地址和数据在总线不复用
    FSMC_Initstruct.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; // 扩展模式A
    FSMC_Initstruct.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; // 数据宽度16位
    FSMC_Initstruct.FSMC_MemoryType = FSMC_MemoryType_SRAM; // 内存类型,SRAM
    FSMC_Initstruct.FSMC_WriteOperation = FSMC_WriteOperation_Enable; // 启用写操作
    FSMC_Initstruct.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
    FSMC_Initstruct.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
    FSMC_Initstruct.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
    FSMC_Initstruct.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
    FSMC_Initstruct.FSMC_WrapMode = FSMC_WrapMode_Disable;
    FSMC_Initstruct.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
    FSMC_Initstruct.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;

    FSMC_Initstruct.FSMC_ReadWriteTimingStruct = &readTiming; // 读写时序配置
    FSMC_Initstruct.FSMC_WriteTimingStruct = &writeTiming; // 写时序配置(扩展模式)
    FSMC_NORSRAMInit(&FSMC_Initstruct);                                                                                  

	FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);  // 使能BANK
}


// 开启LCD
void LCD_Display_on(void)
{
	LCD_BL_ON;
}

// 关闭LCD
void LCD_Display_off(void)
{
	LCD_BL_OFF;
}


// 设置屏幕显示方向
// 0 竖向, 1 横向
void LCD_Display_dir(uint8_t dir)
{	
	if(dir == 0)
	{
		lcddev.DIR = 0;
		lcddev.LCD_Height = 480;
		lcddev.LCD_Width = 320;
		lcddev.wxram = 0x2A;
		lcddev.wyram = 0x2B;
	}else{
		lcddev.DIR = 1;
		lcddev.LCD_Height = 320;
		lcddev.LCD_Width = 480;
		lcddev.wxram = 0x2A;
		lcddev.wyram = 0x2B;
	}
}


// 初始化LCD
void LCD_Init(void)
{   
    GPIO_InitTypeDef GPIO_Initstruct;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);

    GPIO_Initstruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_Initstruct.GPIO_OType = GPIO_OType_PP;
    GPIO_Initstruct.GPIO_Pin = GPIO_Pin_15; // 背光引脚
    GPIO_Initstruct.GPIO_PuPd = GPIO_PuPd_UP;  
    GPIO_Initstruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOA,&GPIO_Initstruct);

    // 初始化FSMC外设引脚
    SRAM_GPIO_Config();
    // 初始化FSMC
    FSMC_SRAM_Config();

	#if USE_FSMC_DMA
		LCD_FSMC_DMA_Config(); // 是否使用DMA
	#endif // USE_FSMC_DMA

    LCD_Delay(500);  

	LCD_WriteReg(0xED);
	LCD_WriteData(0x01);
	LCD_WriteData(0xFE);

	LCD_WriteReg(0xEE);
	LCD_WriteData(0xDE);
	LCD_WriteData(0x21);

	LCD_WriteReg(0xF1);
	LCD_WriteData(0x01);
	LCD_WriteReg(0xDF);
	LCD_WriteData(0x10);

	//VCOMvoltage//
	LCD_WriteReg(0xC4);
	LCD_WriteData(0x8F);	  //5f

	LCD_WriteReg(0xC6);
	LCD_WriteData(0x00);
	LCD_WriteData(0xE2);
	LCD_WriteData(0xE2);
	LCD_WriteData(0xE2);
	LCD_WriteReg(0xBF);
	LCD_WriteData(0xAA);

	LCD_WriteReg(0xB0);
	LCD_WriteData(0x0D);
	LCD_WriteData(0x00);
	LCD_WriteData(0x0D);
	LCD_WriteData(0x00);
	LCD_WriteData(0x11);
	LCD_WriteData(0x00);
	LCD_WriteData(0x19);
	LCD_WriteData(0x00);
	LCD_WriteData(0x21);
	LCD_WriteData(0x00);
	LCD_WriteData(0x2D);
	LCD_WriteData(0x00);
	LCD_WriteData(0x3D);
	LCD_WriteData(0x00);
	LCD_WriteData(0x5D);
	LCD_WriteData(0x00);
	LCD_WriteData(0x5D);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xB1);
	LCD_WriteData(0x80);
	LCD_WriteData(0x00);
	LCD_WriteData(0x8B);
	LCD_WriteData(0x00);
	LCD_WriteData(0x96);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xB2);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x02);
	LCD_WriteData(0x00);
	LCD_WriteData(0x03);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xB3);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xB4);
	LCD_WriteData(0x8B);
	LCD_WriteData(0x00);
	LCD_WriteData(0x96);
	LCD_WriteData(0x00);
	LCD_WriteData(0xA1);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xB5);
	LCD_WriteData(0x02);
	LCD_WriteData(0x00);
	LCD_WriteData(0x03);
	LCD_WriteData(0x00);
	LCD_WriteData(0x04);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xB6);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xB7);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x3F);
	LCD_WriteData(0x00);
	LCD_WriteData(0x5E);
	LCD_WriteData(0x00);
	LCD_WriteData(0x64);
	LCD_WriteData(0x00);
	LCD_WriteData(0x8C);
	LCD_WriteData(0x00);
	LCD_WriteData(0xAC);
	LCD_WriteData(0x00);
	LCD_WriteData(0xDC);
	LCD_WriteData(0x00);
	LCD_WriteData(0x70);
	LCD_WriteData(0x00);
	LCD_WriteData(0x90);
	LCD_WriteData(0x00);
	LCD_WriteData(0xEB);
	LCD_WriteData(0x00);
	LCD_WriteData(0xDC);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xB8);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xBA);
	LCD_WriteData(0x24);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xC1);
	LCD_WriteData(0x20);
	LCD_WriteData(0x00);
	LCD_WriteData(0x54);
	LCD_WriteData(0x00);
	LCD_WriteData(0xFF);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xC2);
	LCD_WriteData(0x0A);
	LCD_WriteData(0x00);
	LCD_WriteData(0x04);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xC3);
	LCD_WriteData(0x3C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x3A);
	LCD_WriteData(0x00);
	LCD_WriteData(0x39);
	LCD_WriteData(0x00);
	LCD_WriteData(0x37);
	LCD_WriteData(0x00);
	LCD_WriteData(0x3C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x36);
	LCD_WriteData(0x00);
	LCD_WriteData(0x32);
	LCD_WriteData(0x00);
	LCD_WriteData(0x2F);
	LCD_WriteData(0x00);
	LCD_WriteData(0x2C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x29);
	LCD_WriteData(0x00);
	LCD_WriteData(0x26);
	LCD_WriteData(0x00);
	LCD_WriteData(0x24);
	LCD_WriteData(0x00);
	LCD_WriteData(0x24);
	LCD_WriteData(0x00);
	LCD_WriteData(0x23);
	LCD_WriteData(0x00);
	LCD_WriteData(0x3C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x36);
	LCD_WriteData(0x00);
	LCD_WriteData(0x32);
	LCD_WriteData(0x00);
	LCD_WriteData(0x2F);
	LCD_WriteData(0x00);
	LCD_WriteData(0x2C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x29);
	LCD_WriteData(0x00);
	LCD_WriteData(0x26);
	LCD_WriteData(0x00);
	LCD_WriteData(0x24);
	LCD_WriteData(0x00);
	LCD_WriteData(0x24);
	LCD_WriteData(0x00);
	LCD_WriteData(0x23);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xC4);
	LCD_WriteData(0x62);
	LCD_WriteData(0x00);
	LCD_WriteData(0x05);
	LCD_WriteData(0x00);
	LCD_WriteData(0x84);
	LCD_WriteData(0x00);
	LCD_WriteData(0xF0);
	LCD_WriteData(0x00);
	LCD_WriteData(0x18);
	LCD_WriteData(0x00);
	LCD_WriteData(0xA4);
	LCD_WriteData(0x00);
	LCD_WriteData(0x18);
	LCD_WriteData(0x00);
	LCD_WriteData(0x50);
	LCD_WriteData(0x00);
	LCD_WriteData(0x0C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x17);
	LCD_WriteData(0x00);
	LCD_WriteData(0x95);
	LCD_WriteData(0x00);
	LCD_WriteData(0xF3);
	LCD_WriteData(0x00);
	LCD_WriteData(0xE6);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xC5);
	LCD_WriteData(0x32);
	LCD_WriteData(0x00);
	LCD_WriteData(0x44);
	LCD_WriteData(0x00);
	LCD_WriteData(0x65);
	LCD_WriteData(0x00);
	LCD_WriteData(0x76);
	LCD_WriteData(0x00);
	LCD_WriteData(0x88);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xC6);
	LCD_WriteData(0x20);
	LCD_WriteData(0x00);
	LCD_WriteData(0x17);
	LCD_WriteData(0x00);
	LCD_WriteData(0x01);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xC7);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xC8);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xC9);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xE0);
	LCD_WriteData(0x16);
	LCD_WriteData(0x00);
	LCD_WriteData(0x1C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x21);
	LCD_WriteData(0x00);
	LCD_WriteData(0x36);
	LCD_WriteData(0x00);
	LCD_WriteData(0x46);
	LCD_WriteData(0x00);
	LCD_WriteData(0x52);
	LCD_WriteData(0x00);
	LCD_WriteData(0x64);
	LCD_WriteData(0x00);
	LCD_WriteData(0x7A);
	LCD_WriteData(0x00);
	LCD_WriteData(0x8B);
	LCD_WriteData(0x00);
	LCD_WriteData(0x99);
	LCD_WriteData(0x00);
	LCD_WriteData(0xA8);
	LCD_WriteData(0x00);
	LCD_WriteData(0xB9);
	LCD_WriteData(0x00);
	LCD_WriteData(0xC4);
	LCD_WriteData(0x00);
	LCD_WriteData(0xCA);
	LCD_WriteData(0x00);
	LCD_WriteData(0xD2);
	LCD_WriteData(0x00);
	LCD_WriteData(0xD9);
	LCD_WriteData(0x00);
	LCD_WriteData(0xE0);
	LCD_WriteData(0x00);
	LCD_WriteData(0xF3);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xE1);
	LCD_WriteData(0x16);
	LCD_WriteData(0x00);
	LCD_WriteData(0x1C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x22);
	LCD_WriteData(0x00);
	LCD_WriteData(0x36);
	LCD_WriteData(0x00);
	LCD_WriteData(0x45);
	LCD_WriteData(0x00);
	LCD_WriteData(0x52);
	LCD_WriteData(0x00);
	LCD_WriteData(0x64);
	LCD_WriteData(0x00);
	LCD_WriteData(0x7A);
	LCD_WriteData(0x00);
	LCD_WriteData(0x8B);
	LCD_WriteData(0x00);
	LCD_WriteData(0x99);
	LCD_WriteData(0x00);
	LCD_WriteData(0xA8);
	LCD_WriteData(0x00);
	LCD_WriteData(0xB9);
	LCD_WriteData(0x00);
	LCD_WriteData(0xC4);
	LCD_WriteData(0x00);
	LCD_WriteData(0xCA);
	LCD_WriteData(0x00);
	LCD_WriteData(0xD2);
	LCD_WriteData(0x00);
	LCD_WriteData(0xD8);
	LCD_WriteData(0x00);
	LCD_WriteData(0xE0);
	LCD_WriteData(0x00);
	LCD_WriteData(0xF3);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xE2);
	LCD_WriteData(0x05);
	LCD_WriteData(0x00);
	LCD_WriteData(0x0B);
	LCD_WriteData(0x00);
	LCD_WriteData(0x1B);
	LCD_WriteData(0x00);
	LCD_WriteData(0x34);
	LCD_WriteData(0x00);
	LCD_WriteData(0x44);
	LCD_WriteData(0x00);
	LCD_WriteData(0x4F);
	LCD_WriteData(0x00);
	LCD_WriteData(0x61);
	LCD_WriteData(0x00);
	LCD_WriteData(0x79);
	LCD_WriteData(0x00);
	LCD_WriteData(0x88);
	LCD_WriteData(0x00);
	LCD_WriteData(0x97);
	LCD_WriteData(0x00);
	LCD_WriteData(0xA6);
	LCD_WriteData(0x00);
	LCD_WriteData(0xB7);
	LCD_WriteData(0x00);
	LCD_WriteData(0xC2);
	LCD_WriteData(0x00);
	LCD_WriteData(0xC7);
	LCD_WriteData(0x00);
	LCD_WriteData(0xD1);
	LCD_WriteData(0x00);
	LCD_WriteData(0xD6);
	LCD_WriteData(0x00);
	LCD_WriteData(0xDD);
	LCD_WriteData(0x00);
	LCD_WriteData(0xF3);
	LCD_WriteData(0x00);
	LCD_WriteReg(0xE3);
	LCD_WriteData(0x05);
	LCD_WriteData(0x00);
	LCD_WriteData(0xA);
	LCD_WriteData(0x00);
	LCD_WriteData(0x1C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x33);
	LCD_WriteData(0x00);
	LCD_WriteData(0x44);
	LCD_WriteData(0x00);
	LCD_WriteData(0x50);
	LCD_WriteData(0x00);
	LCD_WriteData(0x62);
	LCD_WriteData(0x00);
	LCD_WriteData(0x78);
	LCD_WriteData(0x00);
	LCD_WriteData(0x88);
	LCD_WriteData(0x00);
	LCD_WriteData(0x97);
	LCD_WriteData(0x00);
	LCD_WriteData(0xA6);
	LCD_WriteData(0x00);
	LCD_WriteData(0xB7);
	LCD_WriteData(0x00);
	LCD_WriteData(0xC2);
	LCD_WriteData(0x00);
	LCD_WriteData(0xC7);
	LCD_WriteData(0x00);
	LCD_WriteData(0xD1);
	LCD_WriteData(0x00);
	LCD_WriteData(0xD5);
	LCD_WriteData(0x00);
	LCD_WriteData(0xDD);
	LCD_WriteData(0x00);
	LCD_WriteData(0xF3);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xE4);
	LCD_WriteData(0x01);
	LCD_WriteData(0x00);
	LCD_WriteData(0x01);
	LCD_WriteData(0x00);
	LCD_WriteData(0x02);
	LCD_WriteData(0x00);
	LCD_WriteData(0x2A);
	LCD_WriteData(0x00);
	LCD_WriteData(0x3C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x4B);
	LCD_WriteData(0x00);
	LCD_WriteData(0x5D);
	LCD_WriteData(0x00);
	LCD_WriteData(0x74);
	LCD_WriteData(0x00);
	LCD_WriteData(0x84);
	LCD_WriteData(0x00);
	LCD_WriteData(0x93);
	LCD_WriteData(0x00);
	LCD_WriteData(0xA2);
	LCD_WriteData(0x00);
	LCD_WriteData(0xB3);
	LCD_WriteData(0x00);
	LCD_WriteData(0xBE);
	LCD_WriteData(0x00);
	LCD_WriteData(0xC4);
	LCD_WriteData(0x00);
	LCD_WriteData(0xCD);
	LCD_WriteData(0x00);
	LCD_WriteData(0xD3);
	LCD_WriteData(0x00);
	LCD_WriteData(0xDD);
	LCD_WriteData(0x00);
	LCD_WriteData(0xF3);
	LCD_WriteData(0x00);
	LCD_WriteReg(0xE5);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x02);
	LCD_WriteData(0x00);
	LCD_WriteData(0x29);
	LCD_WriteData(0x00);
	LCD_WriteData(0x3C);
	LCD_WriteData(0x00);
	LCD_WriteData(0x4B);
	LCD_WriteData(0x00);
	LCD_WriteData(0x5D);
	LCD_WriteData(0x00);
	LCD_WriteData(0x74);
	LCD_WriteData(0x00);
	LCD_WriteData(0x84);
	LCD_WriteData(0x00);
	LCD_WriteData(0x93);
	LCD_WriteData(0x00);
	LCD_WriteData(0xA2);
	LCD_WriteData(0x00);
	LCD_WriteData(0xB3);
	LCD_WriteData(0x00);
	LCD_WriteData(0xBE);
	LCD_WriteData(0x00);
	LCD_WriteData(0xC4);
	LCD_WriteData(0x00);
	LCD_WriteData(0xCD);
	LCD_WriteData(0x00);
	LCD_WriteData(0xD3);
	LCD_WriteData(0x00);
	LCD_WriteData(0xDC);
	LCD_WriteData(0x00);
	LCD_WriteData(0xF3);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xE6);
	LCD_WriteData(0x11);
	LCD_WriteData(0x00);
	LCD_WriteData(0x34);
	LCD_WriteData(0x00);
	LCD_WriteData(0x56);
	LCD_WriteData(0x00);
	LCD_WriteData(0x76);
	LCD_WriteData(0x00);
	LCD_WriteData(0x77);
	LCD_WriteData(0x00);
	LCD_WriteData(0x66);
	LCD_WriteData(0x00);
	LCD_WriteData(0x88);
	LCD_WriteData(0x00);
	LCD_WriteData(0x99);
	LCD_WriteData(0x00);
	LCD_WriteData(0xBB);
	LCD_WriteData(0x00);
	LCD_WriteData(0x99);
	LCD_WriteData(0x00);
	LCD_WriteData(0x66);
	LCD_WriteData(0x00);
	LCD_WriteData(0x55);
	LCD_WriteData(0x00);
	LCD_WriteData(0x55);
	LCD_WriteData(0x00);
	LCD_WriteData(0x45);
	LCD_WriteData(0x00);
	LCD_WriteData(0x43);
	LCD_WriteData(0x00);
	LCD_WriteData(0x44);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xE7);
	LCD_WriteData(0x32);
	LCD_WriteData(0x00);
	LCD_WriteData(0x55);
	LCD_WriteData(0x00);
	LCD_WriteData(0x76);
	LCD_WriteData(0x00);
	LCD_WriteData(0x66);
	LCD_WriteData(0x00);
	LCD_WriteData(0x67);
	LCD_WriteData(0x00);
	LCD_WriteData(0x67);
	LCD_WriteData(0x00);
	LCD_WriteData(0x87);
	LCD_WriteData(0x00);
	LCD_WriteData(0x99);
	LCD_WriteData(0x00);
	LCD_WriteData(0xBB);
	LCD_WriteData(0x00);
	LCD_WriteData(0x99);
	LCD_WriteData(0x00);
	LCD_WriteData(0x77);
	LCD_WriteData(0x00);
	LCD_WriteData(0x44);
	LCD_WriteData(0x00);
	LCD_WriteData(0x56);
	LCD_WriteData(0x00);
	LCD_WriteData(0x23);
	LCD_WriteData(0x00);
	LCD_WriteData(0x33);
	LCD_WriteData(0x00);
	LCD_WriteData(0x45);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xE8);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x99);
	LCD_WriteData(0x00);
	LCD_WriteData(0x87);
	LCD_WriteData(0x00);
	LCD_WriteData(0x88);
	LCD_WriteData(0x00);
	LCD_WriteData(0x77);
	LCD_WriteData(0x00);
	LCD_WriteData(0x66);
	LCD_WriteData(0x00);
	LCD_WriteData(0x88);
	LCD_WriteData(0x00);
	LCD_WriteData(0xAA);
	LCD_WriteData(0x00);
	LCD_WriteData(0xBB);
	LCD_WriteData(0x00);
	LCD_WriteData(0x99);
	LCD_WriteData(0x00);
	LCD_WriteData(0x66);
	LCD_WriteData(0x00);
	LCD_WriteData(0x55);
	LCD_WriteData(0x00);
	LCD_WriteData(0x55);
	LCD_WriteData(0x00);
	LCD_WriteData(0x44);
	LCD_WriteData(0x00);
	LCD_WriteData(0x44);
	LCD_WriteData(0x00);
	LCD_WriteData(0x55);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xE9);
	LCD_WriteData(0xAA);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);

	LCD_WriteReg(0x00);
	LCD_WriteData(0xAA);

	LCD_WriteReg(0xCF);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xF0);
	LCD_WriteData(0x00);
	LCD_WriteData(0x50);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xF3);
	LCD_WriteData(0x00);

	LCD_WriteReg(0xF9);
	LCD_WriteData(0x06);
	LCD_WriteData(0x10);
	LCD_WriteData(0x29);
	LCD_WriteData(0x00);

	LCD_WriteReg(0x3A);
	LCD_WriteData(0x55);	//66

	LCD_WriteReg(0x11);
	LCD_Delay(100);
	LCD_WriteReg(0x29);
	LCD_WriteReg(0x35);
	LCD_WriteData(0x00);

	LCD_WriteReg(0x36);
	if(lcddev.DIR == 1)
		LCD_WriteData(0x70);
	else
		LCD_WriteData(0x00);

	LCD_WriteReg(0x51);
	LCD_WriteData(0xFF);
	LCD_WriteReg(0x53);
	LCD_WriteData(0x2C);
	LCD_WriteReg(0x55);
	LCD_WriteData(0x82);
	LCD_WriteReg(0x2c);


	// 打开显示
    LCD_Display_on();
	LCD_Clear();
}



void LCD_SetArea(uint16_t LCD_XS,uint16_t LCD_XE,uint16_t LCD_YS,uint16_t LCD_YE)
{
    LCD->LCD_REG = lcddev.wxram;
    LCD->LCD_DATA = LCD_XS >> 8;
    LCD->LCD_DATA = LCD_XS & 0xFF;
    LCD->LCD_DATA = LCD_XE >> 8;
    LCD->LCD_DATA = LCD_XE & 0xFF;    	
    
    LCD->LCD_REG = lcddev.wyram;
    LCD->LCD_DATA = LCD_YS >> 8;
    LCD->LCD_DATA = LCD_YS & 0xFF;
    LCD->LCD_DATA = LCD_YE >> 8;
    LCD->LCD_DATA = LCD_YE & 0xFF;  	
    // 写入内存
    LCD->LCD_REG = lcddev.setram;
}


void LCD_Clear(void)
{
	uint16_t x,y;
	LCD_SetArea(0,lcddev.LCD_Width,0,lcddev.LCD_Height);

	for(x= 0; x < lcddev.LCD_Width; x++)
	{
		for(y = 0; y < lcddev.LCD_Height; y++)
		{
			LCD->LCD_DATA = Background;
		}
	}
}


/*
    设置背景颜色
*/
void LCD_SetBackGround(Color_Size Color)
{
    Background = Color;
    LCD_Clear();
}

// 填充指定的颜色数组
void LCD_Fill_Color(uint16_t xs,uint16_t ys,uint16_t xe,uint16_t ye,const uint16_t* color)
{
	uint32_t sum;
    sum = (ye-ys+1) * (xe-xs+1);
	LCD_SetArea(xs,xe,ys,ye); 
	for(;sum>0;sum--)
    {
		LCD->LCD_DATA = *color++; 
	}
}


/* 次幂函数,用于计算二进制和十六进制数字 */ 
//static uint32_t MyPOW(uint32_t Num, uint8_t pow)
//{
//   uint32_t temp = 1;
//   while(pow--)
//   {
//       temp *= Num;
//   }
//   return temp;
//}


// /*
//     指定行列显示一个字符
//     line:起始行
//     column:起始列
//     Cr:显示的字符
//     Color: 显示的颜色
//     Size: 字符大小
// */
// void LCD_ShowChar(uint8_t line,uint8_t column,char Cr,Color_Size Color,LCD_CharSize Size)
// {
//     W_Bit x;
//     H_Bit y;
//     if(Size == LCD_Char12x24)
//     {
//         if(column*12-12 >= lcddev.LCD_Width) return;
//         if(line*24-24 >= lcddev.LCD_Height) return;
//         LCD_SetArea(column*12-12,column*12-1,line*24-24,line*24-1);
// 		for(y=0;y<24;y++)
//         {
//             for(x=0;x<12;x++)
//             {
//                 if((0x80 >> (x%8)) & LCD_ASC12x24[Cr-' '][(2*y)+(x/8)])
//                 {
// 					LCD->LCD_DATA = Color;
//                 }else{
// 					LCD->LCD_DATA = Background;
//                 }
//             }
//         }
//     }
//     if(Size == LCD_Char16x32)
//     {
//         if(column*16-16 >= lcddev.LCD_Width) return;
//         if(line*32-32 >= lcddev.LCD_Height) return;
//         LCD_SetArea(column*16-16,column*16-1,line*32-32,line*32-1);
//         for(y=0;y<32;y++)
//         {
//             for(x=0;x<16;x++)
//             {
//                 if((0x80 >> (x%8)) & LCD_ASC16x32[Cr-' '][(2*y)+(x/8)])
//                 {
//                     LCD->LCD_DATA = Color;
//                 }else{
//                     LCD->LCD_DATA = Background; 
//                 }
//             }
//         }
//     }
// }




// void LCD_ShowString(uint8_t line,uint8_t column,char *Str,Color_Size Color,LCD_CharSize Size)
// {
//     uint8_t i;
//     for (i = 0; Str[i] != '\0'; i++)
//     {
//         LCD_ShowChar(line, column + i, Str[i],Color,Size);
//     }
// }


// void LCD_ShowNum(uint8_t line, uint8_t column, uint32_t Num,uint8_t length, Color_Size Color,LCD_CharSize Size)
// {
//     uint8_t i;
//     for(i = length; i>0; i--)
//     {
//         LCD_ShowChar(line, column+length-i,((Num%MyPOW(10,i))/(MyPOW(10,i-1)))+0x30,Color,Size);
//     }
// }


// void LCD_ShowSignNum(uint8_t line, uint8_t column, int32_t Num,uint8_t length, Color_Size Color,LCD_CharSize Size)
// {
//     uint32_t temp;
//     if(Num>0){
//         temp = Num;
//         LCD_ShowChar(line,column,'+',Color,Size);
//         LCD_ShowNum(line,column+1,temp,length,Color,Size);
//     }
//     else if(Num<0)
//     {
//         temp = -Num;
//         LCD_ShowChar(line,column,'-',Color,Size);
//         LCD_ShowNum(line,column+1,temp,length,Color,Size);
//     }
//     else
//     {
//         LCD_ShowNum(line,column,Num,length,Color,Size);
//     }
// }


// /*
//     显示十六进制数
// */
// void LCD_ShowHexNum(uint8_t line, uint8_t column, uint32_t HexNum,uint8_t length, Color_Size Color,LCD_CharSize Size)
// {
//     uint8_t i,Num;
//     for(i = length; i>0; i--)
//     {
//         Num = (HexNum / MyPOW(16,i-1))% 16;
//         if(Num < 10)
//         {
//             LCD_ShowChar(line,column+(length-i),Num+'0',Color,Size);
//         }
//         else if(10 <= Num <= 15)
//         {
//             Num -= 10;
//             LCD_ShowChar(line,column+(length-i),Num+'A',Color,Size);
//         }
//     }

// }

// /*
//     显示二进制数
// */
// void LCD_ShowBinNum(uint8_t line,uint8_t Column,uint16_t BinNum,uint8_t length,Color_Size Color,LCD_CharSize Size)
// {
//     uint8_t i;
//     for(i = 0; i < length; i++)
//     {
//         if((BinNum >> (length-i-1)) & 0x0001)
//         {
//             LCD_ShowChar(line,Column+i,'1',Color,Size);
//         }
//         else
//         {
//             LCD_ShowChar(line,Column+i,'0',Color,Size);
//         }
//     }
// }

// /*
//     显示16x16大小汉字
// */
// void LCD_ShowChinese16x16(uint8_t line,uint8_t Column,char *cnstr,uint8_t length,Color_Size Color)
// {
//     uint8_t i,x,y,z;
//     char cntemp[LCD_CN_WIDTH + 1];
//     for(z = 0; z<length; z++)
//     {
//         strncpy(cntemp,cnstr+(LCD_CN_WIDTH*z),LCD_CN_WIDTH);
//         for(i = 0; strcmp(LCD_Chinese16x16[i].Index,"") != 0;i++)
//         {
//             if(strcmp(LCD_Chinese16x16[i].Index,cntemp) == 0)
//             {
//                 LCD_SetArea(Column*16-16,Column*16-1,line*16-16,line*16-1);
//                 for(y=0;y<16;y++)
//                 {
//                     for(x=0;x<16;x++)
//                     {
//                         if((0x80 >> (x%8)) & LCD_Chinese16x16[i].Data[(2*y)+(x/8)])
//                         {
//                             LCD->LCD_DATA = Color;
//                         }else{
// 							LCD->LCD_DATA = Background;
//                         }
//                     }
//                 }
//                 break;
//             }
//         }
//         if(strcmp(LCD_Chinese16x16[i].Index,"") == 0)
//         {
//             LCD_SetArea(Column*16-16,Column*16-1,line*16-16,line*16-1);
// 			for(y=0;y<16;y++)
//             {
//                 for(x=0;x<16;x++)
//                 {
//                     if((0x80 >> (x%8)) & LCD_Chinese16x16[i].Data[(2*y)+(x/8)])
//                     {
//                         LCD->LCD_DATA = Color;
//                     }else{
//                         LCD->LCD_DATA = Background;
//                     }
//                 }
//             }
//         }
//         Column++;
//     }
// }

// /*
//     显示32x32大小汉字
// */
// void LCD_ShowChinese32x32(uint8_t line,uint8_t Column,char *cnstr,uint8_t length, Color_Size Color)
// {
//     uint8_t i,x,y,z;
//     char cntemp[LCD_CN_WIDTH + 1];
//     for(z = 0; z<length; z++)
//     {
//         strncpy(cntemp,cnstr+(LCD_CN_WIDTH*z),LCD_CN_WIDTH);
//         for(i = 0; strcmp(LCD_Chinese32x32[i].Index,"") != 0;i++)
//         {
//             if(strcmp(LCD_Chinese32x32[i].Index,cntemp) == 0)
//             {       
//                 LCD_SetArea(Column*32-32,Column*32-1,line*32-32,line*32-1);
// 				for(y=0;y<32;y++)
//                 {
//                     for(x=0;x<32;x++)
//                     {
//                         if((0x80 >> (x%8)) & LCD_Chinese32x32[i].Data[(4*y)+(x/8)])
//                         {
//                             LCD->LCD_DATA = Color;
//                         }else{
// 							LCD->LCD_DATA = Background;
//                         }
//                     }
//                 } 
//                 break; 
//             }
//         }
//         if(strcmp(LCD_Chinese32x32[i].Index,"") == 0)
//         {
//             LCD_SetArea(Column*32-32,Column*32-1,line*32-32,line*32-1);
// 			for(y=0;y<32;y++)
//             {
//                 for(x=0;x<32;x++)
//                 {
//                     if((0x80 >> (x%8)) & LCD_Chinese32x32[i].Data[(4*y)+(x/8)])
//                     {
// 						LCD->LCD_DATA = Color;
// 					}else{
// 						LCD->LCD_DATA = Background;
// 					}
//                 }
//             }  
//         }
//         Column++;
//     }
// }